#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
#include "snake.h"
#include "snakeio.h"
#include "game.h"
#include "SDL3/SDL_log.h"
#include "SDL3/SDL_timer.h"
#include "SDL3/SDL_main.h"
#include "SDL3_image/SDL_image.h"


SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
char host[128] = "127.0.0.1";
int port = 8080;


int read_config(char *host_out, size_t host_size, int *port_out, char *player_name_out, size_t player_name_size) {
    FILE *file = fopen("config.properties", "r");
    if (!file) {
        perror("无法打开 config.properties");
        return -1; // 错误代码，无法打开文件
    }
    char line[128];
    while (fgets(line, sizeof(line), file)) {
        // 去掉换行符
        line[strcspn(line, "\r\n")] = 0;

        // 处理 host
        if (strncmp(line, "host=", 5) == 0) {
            strncpy(host_out, line + 5, host_size - 1);
            host_out[host_size - 1] = '\0';
        }
        // 处理 port
        else if (strncmp(line, "port=", 5) == 0) {
            *port_out = atoi(line + 5);
        }
        // 处理 player-name
        else if (strncmp(line, "player-name=", 12) == 0) {
            char *player_name = line + 12; // Skip the "player-name=" part

            // 检查是否需要替换 %R%
            if (strstr(player_name, "%R%")) {
                char random_str[5]; // 4 chars + null terminator
                generateRandomString(random_str, 4);

                // 替换 %R% 为随机字符串
                char *replace_pos = strstr(player_name, "%R%");
                if (replace_pos) {
                    strncpy(replace_pos, random_str, 4);
                    memmove(replace_pos + 4, replace_pos + 3, strlen(replace_pos + 3) + 1);
                }
            }

            // 拷贝 player-name 到输出缓冲区
            strncpy(player_name_out, player_name, player_name_size - 1);
            player_name_out[player_name_size - 1] = '\0';
        }
    }

    fclose(file);
    return 0; // 成功读取
}

void loadWindowIcon() {
    SDL_Surface *icon = IMG_Load("assets/icon.png");
    if (!icon) {
        SDL_Log("Failed to load icon: %s", SDL_GetError());
    }
    if (icon) {
        SDL_SetWindowIcon(window, icon);
        SDL_DestroySurface(icon);
    }
}

int main(int argc, char *argv[]) {
    if (read_config(host, sizeof(host), &port, playerName, sizeof(playerName)) != 0) {
        return 1; // 配置读取失败
    }
    Uint64 lastFrameTime = 0;
    float accumulator = 0.0f;
    lastFrameTime = SDL_GetTicks();
    if (pre_init(host, port) != 0) {
        return 1;
    }
    while (!inited) {
        serverTick();
    }

    init();

    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        SDL_Log("SDL初始化失败: %s", SDL_GetError());
        return 1;
    }

    window = SDL_CreateWindow("Snake4c", WINDOW_WIDTH, WINDOW_HEIGHT, 0);

    if (!window) {
        SDL_Log("窗口创建失败: %s", SDL_GetError());
        SDL_Quit();
        return 1;
    }

    loadWindowIcon();

    renderer = SDL_CreateRenderer(window, NULL);
    if (!renderer) {
        SDL_Log("渲染器创建失败: %s", SDL_GetError());
        SDL_DestroyWindow(window);
        SDL_Quit();
        return 1;
    }
    while (running) {
        const Uint64 currentTime = SDL_GetTicks();
        const int frameTime = currentTime - lastFrameTime;
        lastFrameTime = currentTime;
        accumulator += frameTime;
        handleInput();
        const int newTick = serverTick(); // 弹包，更新帧缓存
        if (newTick >= 0 && newTick > sTick) {
            sTick = newTick;
        } else {
            continue;
        }
        const int targetFrame = sTick - delayFrames;
        if ((targetFrame - cTick > 20 || cTick - targetFrame > 20) && !syncing && syncCounter > 0) {
            printf("帧差过大，进行全量同步\n");
            sendPacketByType(PACKET_TYPE_SYNC);
            cTick = targetFrame; // 跳到目标帧，丢弃中间帧
            accumulator = 0; // 清空累积时间，防止瞬间多逻辑更新
            continue;
        }
        while (accumulator >= (float) DELTA_TIME && cTick <= targetFrame) {
            Packet *pkt = framebuffer_get(cTick);
            if (pkt) {
                for (int i = 0; i < pkt->frame.frameCount; i++) {
                    PacketFrameItem *item = &pkt->frame.frames[i];
                    if (item->type == PACKET_TYPE_JOIN) {
                    }
                }
                updateLogic(pkt);
                framebuffer_clear(cTick);
            }
            cTick++;
            accumulator -= (float) DELTA_TIME;
        }
        const float alpha = accumulator / (float) DELTA_TIME;
        render(alpha);
    }
    cleanup();
    return 0;
}
